import $ from 'jquery';

class QueryStore {
  set(target = null) {
    let hash = this.getHash()
      , deferred = $.Deferred()
      , value = target ? $.param(target, false) : hash.query;

    if (hash.route && value) {
      sessionStorage[hash.key] = value;

      deferred.resolve({
        key: hash.key,
        route: hash.route,
        query: value
      });
    } else {
      deferred.reject();
    }

    return deferred.promise();
  } // set

  get() {
    return this.unparams(this.getString());
  } // get

  getString() {
    let hash = this.getHash();
    if (hash.route && hash.query) {
      return hash.query;
    } else if (hash.route) {
      return sessionStorage[hash.key] || '';
    } else {
      return '';
    }
  } // getString

  getHash() {
    let hash = location.hash
      , index = hash.indexOf('?')
      , query = index >= 0 ? hash.substr(index + 1) : ''
      , route = index >= 0 ? hash.substr(0, index) : hash;

    let key = `${ location.protocol }://${ location.host }${ location.pathname }${ location.search }${ route }`;
    return {
      key,
      route,
      query
    };
  } // getHash

  params(target) {
    if (!target) {
      return '';
    }

    return $.param(target, false);
  } // params

  unparams(queryString) {
    let hash = (queryString + '').indexOf('#');
    if (hash !== -1) {
        queryString = queryString.substr(hash + 1);
    }

    let result = {};
    if (!queryString) {
        return result;
    }

    let getValue = function (source, parameter, value) {
        if (!parameter) {
            return source;
        }
        let q = /^\[([a-zA-Z-_\d$.]*)\]/;
        let l = q.exec(parameter);
        let i = l[1];
        if (i) {
            if ($.isNumeric(i)) {
                source = source || [];
            } else {
                source = source || {};
            } if (l[0] === parameter) {
                source[i] = value;
            } else {
                source[i] = getValue(source[i], parameter.substr(l[0].length), value);
            }
        } else {
            if (!$.isArray(source)) {
                source = [];
            }
            source.push(value);
        }
        return source;
    };
    let parameters = queryString.split("&");
    let regexp = /([a-zA-Z-_\d$.]*)\[([a-zA-Z-_\d$.]*)\]/;

    for (let i = 0, e = parameters.length; i < e; i++) {
        let values = parameters[i].split("=");
        let n = decodeURIComponent((values[0] || '').replace(/\+/g, "%20"));
        let k = decodeURIComponent((values[1] || '').replace(/\+/g, "%20"));
        let array = regexp.exec(n);
        if ($.isArray(array)) {
            let m = array[1];
            result[m] = getValue(result[m], n.substr(m.length), k);
        } else {
            result[n] = k;
        }
    }
    return result;
  } // unparams
}

export default new QueryStore();